home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / russell / gc32.lha / obj_map.c < prev    next >
C/C++ Source or Header  |  1993-07-14  |  4KB  |  136 lines

  1. /* 
  2.  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3.  * Copyright (c) 1991, 1992 by Xerox Corporation.  All rights reserved.
  4.  *
  5.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  6.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  7.  *
  8.  * Permission is hereby granted to copy this garbage collector for any purpose,
  9.  * provided the above notices are retained on all copies.
  10.  */
  11.   
  12. /* Routines for maintaining maps describing heap block
  13.  * layouts for various object sizes.  Allows fast pointer validity checks
  14.  * and fast location of object start locations on machines (such as SPARC)
  15.  * with slow division.
  16.  *
  17.  * Boehm, February 6, 1992 1:00:09 pm PST
  18.  */
  19.  
  20. # include "gc_private.h"
  21.  
  22. char * GC_invalid_map = 0;
  23.  
  24. /* Invalidate the object map associated with a block.    Free blocks    */
  25. /* are identified by invalid maps.                    */
  26. void GC_invalidate_map(hhdr)
  27. hdr *hhdr;
  28. {
  29.     register int displ;
  30.     
  31.     if (GC_invalid_map == 0) {
  32.         GC_invalid_map = GC_scratch_alloc(MAP_SIZE);
  33.         if (GC_invalid_map == 0) {
  34.             GC_err_printf0(
  35.                 "Cant initialize GC_invalid_map: insufficient memory\n");
  36.             EXIT();
  37.         }
  38.         for (displ = 0; displ < HBLKSIZE; displ++) {
  39.             MAP_ENTRY(GC_invalid_map, displ) = OBJ_INVALID;
  40.         }
  41.     }
  42.     hhdr -> hb_map = GC_invalid_map;
  43. }
  44.  
  45. /* Consider pointers that are offset bytes displaced from the beginning */
  46. /* of an object to be valid.                                            */
  47. void GC_register_displacement(offset) 
  48. word offset;
  49. {
  50. # ifndef ALL_INTERIOR_POINTERS
  51.     DCL_LOCK_STATE;
  52.     
  53.     DISABLE_SIGNALS();
  54.     LOCK();
  55.     GC_register_displacement_inner(offset);
  56.     UNLOCK();
  57.     ENABLE_SIGNALS();
  58. # endif
  59. }
  60.  
  61. void GC_register_displacement_inner(offset) 
  62. word offset;
  63. {
  64. # ifndef ALL_INTERIOR_POINTERS
  65.     register int i;
  66.     
  67.     if (offset > MAX_OFFSET) {
  68.         ABORT("Bad argument to GC_register_displacement");
  69.     }
  70.     if (!GC_valid_offsets[offset]) {
  71.       GC_valid_offsets[offset] = TRUE;
  72.       GC_modws_valid_offsets[offset % sizeof(word)] = TRUE;
  73.       for (i = 0; i <= MAXOBJSZ; i++) {
  74.           if (GC_obj_map[i] != 0) {
  75.              if (i == 0) {
  76.                GC_obj_map[i][offset + HDR_BYTES] = BYTES_TO_WORDS(offset);
  77.              } else {
  78.                register int j;
  79.                register int lb = WORDS_TO_BYTES(i);
  80.                
  81.                if (offset < lb) {
  82.                  for (j = offset + HDR_BYTES; j < HBLKSIZE; j += lb) {
  83.                    GC_obj_map[i][j] = BYTES_TO_WORDS(offset);
  84.                  }
  85.                }
  86.              }
  87.           }
  88.       }
  89.     }
  90. # endif
  91. }
  92.  
  93.  
  94. /* Add a heap block map for objects of size sz to obj_map.    */
  95. /* Return FALSE on failure.                    */
  96. bool GC_add_map_entry(sz)
  97. word sz;
  98. {
  99.     register int obj_start;
  100.     register int displ;
  101.     register char * new_map;
  102.     
  103.     if (sz > MAXOBJSZ) sz = 0;
  104.     if (GC_obj_map[sz] != 0) {
  105.         return(TRUE);
  106.     }
  107.     new_map = GC_scratch_alloc(MAP_SIZE);
  108.     if (new_map == 0) return(FALSE);
  109. #   ifdef PRINTSTATS
  110.         GC_printf1("Adding block map for size %lu\n", (unsigned long)sz);
  111. #   endif
  112.     for (displ = 0; displ < HBLKSIZE; displ++) {
  113.         MAP_ENTRY(new_map,displ) = OBJ_INVALID;
  114.     }
  115.     if (sz == 0) {
  116.         for(displ = 0; displ <= MAX_OFFSET; displ++) {
  117.             if (OFFSET_VALID(displ)) {
  118.                 MAP_ENTRY(new_map,displ+HDR_BYTES) = BYTES_TO_WORDS(displ);
  119.             }
  120.         }
  121.     } else {
  122.         for (obj_start = HDR_BYTES;
  123.              obj_start + WORDS_TO_BYTES(sz) <= HBLKSIZE;
  124.              obj_start += WORDS_TO_BYTES(sz)) {
  125.              for (displ = 0; displ < WORDS_TO_BYTES(sz); displ++) {
  126.                  if (OFFSET_VALID(displ)) {
  127.                      MAP_ENTRY(new_map, obj_start + displ) =
  128.                                      BYTES_TO_WORDS(displ);
  129.                  }
  130.              }
  131.         }
  132.     }
  133.     GC_obj_map[sz] = new_map;
  134.     return(TRUE);
  135. }
  136.